package yxy.game.pm2.module.wuchao;

import yxy.cherry.battle.module.Position;
import yxy.cherry.battle.module.record.FighterPosition;
import yxy.cherry.battle.module.record.result.BattleResult;
import yxy.cherry.battle.module.record.result.StatisticFighter;
import yxy.cherry.data.DataCenter;
import yxy.cherry.data.bean.glorywuchao;
import yxy.cherry.data.bean.wuchaoitem;
import yxy.game.pm2.Result;
import yxy.game.pm2.bean.Hero;
import yxy.game.pm2.bean.PlayerBean;
import yxy.game.pm2.message.BattleMessage;
import yxy.game.pm2.message.HeroMessage;
import yxy.game.pm2.message.WuchaoMessage;
import yxy.game.pm2.module.battle.*;
import yxy.game.pm2.module.battle.FighterModule.InitHpLossRatio;
import yxy.game.pm2.module.hero.HeroHandle;
import yxy.game.pm2.module.shop.handle.WuchaoShopHandle;
import yxy.game.pm2.module.wuchao.event.*;
import yxy.game.pm2.module.wuchao.event.WuchaoEvent.EventType;

import java.util.*;

public class WuchaoHandle {

	public Result info(String playerCode, WuchaoMessage.WuchaoUIResponse.Builder response) {
		try {
			WuchaoModule wuchaoModule = WuchaoModule.get(playerCode);

			int stage = wuchaoModule.getStage();
			response.setStage(stage);
			if (stage <= 0) {
				HeroHandle heroHandle = new HeroHandle();
				Collection<Hero> heros = heroHandle.getHeros(playerCode);
				for (Hero hero : heros) {
					try {
						response.addHeros(heroHandle.getHeroSimple(playerCode, hero));
					} catch (Exception e) {
					}
				}
				return Result.Success;
			}
			response.setPassStage(wuchaoModule.getPassStage());

			Collection<WuchaoHero> heros = wuchaoModule.getHeros().values();
			for (WuchaoHero hero : heros) {
				{
					HeroMessage.HeroSimple.Builder builder = HeroMessage.HeroSimple.newBuilder();
					builder.setCode(hero.getCode());
					builder.setDataId(hero.getFighterModule().getHeroId());
					builder.setLevel(hero.getFighterModule().getLevel());
					builder.setStar(hero.getFighterModule().getStarlv());
					builder.setBattlepower(hero.getPower());
					response.addHeros(builder);
				}
				{
					HeroMessage.HeroHp.Builder builder = HeroMessage.HeroHp.newBuilder();
					builder.setCode(hero.getCode());
					builder.setHp(hero.getHeroHp());

					response.addHps(builder);
				}
			}
			Collection<WuchaoEvent> events = wuchaoModule.getEvents().values();
			for (WuchaoEvent event : events) {
				if (event.isOver()) {
					continue;
				}
				WuchaoMessage.WuchaoEvent info = event.packageInfo();
				response.addEvent(info);
			}
			response.setCure(wuchaoModule.getCure());
			response.setPoison(wuchaoModule.getPoison());
			for (Integer boxId : wuchaoModule.getBox()) {
				response.addBox(boxId);// 已领宝箱id
			}

			response.setEndtime(wuchaoModule.timeline().getEndTime().getMillis());

			return Result.Success;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public Result format(WuchaoModule wuchaoModule, List<String> heroCodes, WuchaoMessage.WuchaoFormatResponse.Builder response) {
		String playerCode = wuchaoModule.getPlayerCode();
		if (wuchaoModule.getStage() > 0) {
			return Result.ParamError;
		}
		HashSet<String> heroCodeSet = new HashSet<>(heroCodes);
		if (heroCodeSet.size() <= 0 || heroCodeSet.size() > 6) {
			return Result.WuchaoFormat;// 武将数量不对
		}
		try {
			if (wuchaoModule.tryLock()) {
				HeroHandle heroHandle = new HeroHandle();

				ArrayList<WuchaoHero> heroList = new ArrayList<>();

				for (String heroCode : heroCodeSet) {
					Hero hero = heroHandle.getHero(playerCode, heroCode);
					if (hero == null) {
						return Result.HeroNotExists;
					}

					// 生成快照
					FighterModule fighterModule = new BattleHandle().fighter(playerCode, hero, null);

					WuchaoHero wuchaoHero = new WuchaoHero();
					wuchaoHero.setCode(hero.getCode());
					wuchaoHero.setHeroHp(10000);
					wuchaoHero.setPower(new BattleHandle().power(playerCode, hero));
					wuchaoHero.setFighterModule(fighterModule);

					heroList.add(wuchaoHero);
				}

				wuchaoModule.init(heroList);

				RankWuchao.getRank(playerCode).put(playerCode, wuchaoModule.getStage(), wuchaoModule.getExplore());
			}
		} catch (Exception e) {
			return Result.DataError;
		} finally {
			wuchaoModule.unlock();
		}

		return Result.Success;
	}

	protected String code() {
		return BattleType.FORTDEFEAT.name();
	}

	public Result battleResponseExecute(WuchaoModule wuchaoModule, String eventCode, String heroCode, WuchaoMessage.WuchaoChanllengeResponse.Builder response)
			throws Exception {
		String playerCode = wuchaoModule.getPlayerCode();

		if (wuchaoModule.getStage() <= 0) {
			return Result.WuchaoNotStart;// 没有开始挑战
		}

		WuchaoEvent event = wuchaoModule.getEvents().get(eventCode);

		if (event == null || event.isOver()) {
			return Result.WuchaoEnemyDead;//  事件不可用
		}
		if (!(event instanceof WuchaoEventEnemy)) {
			return Result.ParamError;//  事件不可用
		}
		if (event.getEventType().equals(EventType.Boss)) {
			// 检查是否还有普通敌人在场
			for (WuchaoEvent evt : wuchaoModule.getEvents().values()) {
				if (evt.getEventType().equals(EventType.Enemy)) {
					if (!evt.isOver()) {
						return Result.WuchaoEnemyNormal;//  还有普通敌人没有被消灭
					}
				}
			}
		}

		int dataId = ((WuchaoEventEnemy) event).getDataId();
		glorywuchao data = DataCenter.getData(dataId, glorywuchao.class);
		if (data == null) {
			return Result.DataError;// 数据不可用
		}
		WuchaoHero hero = wuchaoModule.getHeros().get(heroCode);
		if (hero == null || hero.getHeroHp() <= 0) {
			return Result.WuchaoEnemyHeroDead;// 你不能派死掉的武将出战
		}

		BattleHandle battleHandle = new BattleHandle();

		BattleModule battleModule = BattleModule.create(playerCode);
		battleModule.setType(BattleType.WUCHAO);
		battleModule.setCode(code());

		// 玩家的team
		TeamModule teamA = teamPlayer(playerCode, hero);
		battleModule.setTeamA(teamA);

		// 敌人的team
		TeamModule teamB = teamEnemy((WuchaoEventEnemy) event);
		battleModule.setTeamB(teamB);

		BattleMessage.BattleExecuteResponse res = battleHandle.battleResponseExecute(battleModule, 20, false, null);

		// 保存血量
		for (StatisticFighter fighter : battleModule.getStatistics()) {
			if (fighter.getPos().equals(FighterPosition.FML)) {
				int ratio = (int) (fighter.getHpc() * 10000 / fighter.getHpu());
				if (hero != null && ratio < 10000) {
					hero.setHeroHp(ratio);
				}
			}
			if (fighter.getPos().equals(FighterPosition.FMR)) {
				int ratio = (int) (fighter.getHpc() * 10000 / fighter.getHpu());
				((WuchaoEventEnemy) event).setHp(ratio);
			}
		}

		boolean isWin = battleModule.getBattleResult().equals(BattleResult.LEFT_WIN);
		if (isWin) {
			killEnemy(playerCode, wuchaoModule, (WuchaoEventEnemy) event);
		} else {

		}

		wuchaoModule.set();

		RankWuchao.getRank(playerCode).put(playerCode, wuchaoModule.getStage(), wuchaoModule.getExplore());

		// 封装消息
		response.setCode(event.getCode());
		response.setBattleResp(res);// 录像
		response.setBattleResult(battleModule.getBattleResult().getNumber());// 战果

		return Result.Success;
	}

	public void killEnemy(String playerCode, WuchaoModule wuchaoModule, WuchaoEventEnemy event) {
		int dataId = event.getDataId();
		glorywuchao data = DataCenter.getData(dataId, glorywuchao.class);
		event.setOver(true);
		wuchaoModule.setExplore(wuchaoModule.getExplore() + data.getExplore());
		// 生成新事件
		for (int i = 0; i < data.getType().length; i++) {
			int type = data.getType()[i];
			int param = data.getParameter()[i];
			EventType eventType = EventType.forNumber(type);
			if (eventType == null) {
				continue;
			}
			WuchaoEvent wuchaoEvent = null;
			switch (eventType) {
			case NewGoods: {
				wuchaoEvent = WuchaoEventNewGoods.create(new WuchaoShopHandle().getModule(playerCode));
			}
				break;
			case Guess: {
				wuchaoEvent = WuchaoEventGuess.create();
			}
				break;
			case Chest: {
				wuchaoEvent = WuchaoEventChest.create();
			}
				break;
			case Drop: {
				wuchaoitem wuchaoitemdata = DataCenter.getData(param, wuchaoitem.class);
				wuchaoEvent = WuchaoEventDrop.create(wuchaoitemdata);
			}
				break;
			case Quiz: {
				wuchaoEvent = WuchaoEventQuiz.create();
			}
				break;
			default:
			}
			if (wuchaoEvent != null) {
				wuchaoEvent.setCode(WuchaoEvent.randomCode(wuchaoModule));
				wuchaoEvent.setLevel(event.getLevel());
				wuchaoModule.getEvents().put(wuchaoEvent.getCode(), wuchaoEvent);
			}
		}
	}

	private TeamModule teamPlayer(String playerCode, WuchaoHero hero) {
		TeamModule team = new TeamModule();
		FighterModule fighterModule = hero.getFighterModule();
		fighterModule.setInitHp(new InitHpLossRatio(hero.getHeroHp()));
		team.addfighter(Position.FM, fighterModule);
		// 信息
		PlayerBean playerBean = PlayerBean.get(playerCode);
		team.setName(playerBean.getName());
		team.setHead(playerBean.getHead());
		team.setLevel(playerBean.getLevel());
		team.setPower(team.power());

		return team;
	}

	private TeamModule teamEnemy(WuchaoEventEnemy enemy) {
		glorywuchao data = DataCenter.getData(enemy.getDataId(), glorywuchao.class);

		TeamModule team = new TeamModule();
		// 武将
		int heroid = data.getHeroid()[0];
		int level = data.getGrade()[0];
		int anger = data.getInitialangerup()[0];
		int stage = 0;
		int star = 0;

		//如果找不到heroid默认不变  stage和star为0
		HashMap<String, Integer> map = BattleHandle.addStarAndStage(heroid, stage, star, level);
		heroid = map.get("heroid");
		stage = map.get("stage");
		star = map.get("star");

		FighterModule fighterModule = FighterModule.create(heroid, level, stage, star, anger);

		fighterModule.setProperty(PropertyModule.create(BattleHandle.getOppositePropertyData(heroid, level, stage, star, anger)));

		fighterModule.setInitHp(new InitHpLossRatio(enemy.getHp()));

		team.addfighter(Position.FM, fighterModule);

		// 信息
		team.setName(data.getName());
		team.setHead(data.getHeadid());
		team.setPower(team.power());

		return team;
	}

	public Result nextStage(WuchaoModule wuchaoModule) {
		String playerCode = wuchaoModule.getPlayerCode();
		if (wuchaoModule.getStage() <= 0) {
			return Result.WuchaoNotStart;// 没有开始挑战
		}

		for (WuchaoEvent evt : wuchaoModule.getEvents().values()) {
			if (evt instanceof WuchaoEventEnemy && !evt.isOver()) {
				return Result.WuchaoStageNotOver;// 关卡尚未结束
			}
		}

		wuchaoModule.initStage(wuchaoModule.getStage() + 1);
		wuchaoModule.setPassStage(wuchaoModule.getPassStage() + 1);
		if (wuchaoModule.getBestStage() < wuchaoModule.getStage()) {
			wuchaoModule.setBestStage(wuchaoModule.getStage());
		}
		wuchaoModule.set();

		RankWuchao.getRank(playerCode).put(playerCode, wuchaoModule.getStage(), wuchaoModule.getExplore());

		return Result.Success;
	}
}
